{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## CrewAI:Crew\n",
    "\n",
    "什么是Crew?\n",
    "    \n",
    "Crew代表了一组相互合作的agent，共同实现一系列Task。\n",
    "\n",
    "每个Crew都会定义：\n",
    "- Task执行的策略\n",
    "- 参与的Agent的协作方式\n",
    "- 以及整体的工作流workflow"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "from crewai import Agent, Crew, Task, Process\n",
    "# from crewai_tools import YourCustomTool"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "ename": "ImportError",
     "evalue": "cannot import name 'TaskOutput' from 'crewai' (d:\\Python312\\Lib\\site-packages\\crewai\\__init__.py)",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mImportError\u001b[0m                               Traceback (most recent call last)",
      "Cell \u001b[1;32mIn[4], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mcrewai\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m Agent, Crew, Task, Process, TaskOutput\n\u001b[0;32m      2\u001b[0m \u001b[38;5;66;03m# from crewai_tools import YourCustomTool\u001b[39;00m\n\u001b[0;32m      4\u001b[0m \u001b[38;5;28;01mclass\u001b[39;00m \u001b[38;5;21;01mYourCrewName\u001b[39;00m:\n",
      "\u001b[1;31mImportError\u001b[0m: cannot import name 'TaskOutput' from 'crewai' (d:\\Python312\\Lib\\site-packages\\crewai\\__init__.py)"
     ]
    }
   ],
   "source": [
    "\n",
    "\n",
    "class YourCrewName:\n",
    "    def agent_one(self) -> Agent:\n",
    "        return Agent(\n",
    "            role=\"Data Analyst\",\n",
    "            goal=\"Analyze data trends in the market\",\n",
    "            backstory=\"An experienced data analyst with a background in economics\",\n",
    "            verbose=True,\n",
    "            tools=[YourCustomTool()]\n",
    "        )\n",
    "\n",
    "    def agent_two(self) -> Agent:\n",
    "        return Agent(\n",
    "            role=\"Market Researcher\",\n",
    "            goal=\"Gather information on market dynamics\",\n",
    "            backstory=\"A diligent researcher with a keen eye for detail\",\n",
    "            verbose=True\n",
    "        )\n",
    "\n",
    "    def task_one(self) -> Task:\n",
    "        return Task(\n",
    "            description=\"Collect recent market data and identify trends.\",\n",
    "            expected_output=\"A report summarizing key trends in the market.\",\n",
    "            agent=self.agent_one()\n",
    "        )\n",
    "\n",
    "    def task_two(self) -> Task:\n",
    "        return Task(\n",
    "            description=\"Research factors affecting market dynamics.\",\n",
    "            expected_output=\"An analysis of factors influencing the market.\",\n",
    "            agent=self.agent_two()\n",
    "        )\n",
    "    \n",
    "    def callback_function(output: TaskOutput):\n",
    "    # Do something after the task is completed\n",
    "    # Example: Send an email to the manager\n",
    "        print(f\"\"\"\n",
    "            Task completed!\n",
    "            Task: {output.description}\n",
    "            Output: {output.raw}\n",
    "        \"\"\")\n",
    "\n",
    "    def crew(self) -> Crew:\n",
    "        return Crew(\n",
    "            agents=[self.agent_one(), self.agent_two()],        # 构成crew的agent列表\n",
    "            tasks=[self.task_one(), self.task_two()],           # 分配给crew的任务列表\n",
    "            process=Process.sequential,                         # 过程流的形式 (e.g., sequential顺序, hierarchical分层)，默认是sequential\n",
    "            verbose=True,                                       # 记录的详细级别，默认是False\n",
    "            planning = True,                                    # 是否开启计划模式，在每个crew迭代之前激活时，所有crew数据会发送给Planner agent以计划任务。并且该planning将会添加到每个任务描述中。\n",
    "            planning_llm = my_planning_llm,                     # 指定planning的llm\n",
    "            manager_agent = self.agent_one(),                   # sets a custom agent that will be used as a manager.\n",
    "            manager_llm=my_llm,                                 # 在分层模式中，经理agent会用来指定任务分工\n",
    "            function_calling_llm = my_func_llm,                 # 用来选择工具的llm，如果agent里配置了，以具体agent的为准，该agent会覆盖这个设置\n",
    "            config = Json/Dict[str, Any],                       # 可选配置项\n",
    "            max_rmp = 10,                                       # 每分钟llm最大调用次数，默认是None \n",
    "            language = \"Chinese\",                               # 语言，默认是English  \n",
    "            memory=True,                                        # Crewai框架引入了一个复杂的存储系统，旨在显着增强AI代理的功能。该系统包括short-term memory（用RAG记最近的交互和结果）， long-term memory(学方法论和做事原则) ， entity memory（只记实体）和contextual memory（前三者的组合），每个内存都在帮助辅助agent记住，推理和从过去的交互中学习的独特目的。内存将默认使用OpenAI嵌入，但是您可以通过将embedder设置为其他模型来更改它\n",
    "            memory_config={\n",
    "                \"provider\": \"mem0\",\n",
    "                \"config\": {\"user_id\": \"john\", \"org_id\": \"my_org_id\", \"project_id\": \"my_project_id\"},\n",
    "            },                                                  # 使用第三方memory服务的配置，例如mem0\n",
    "            cache = True,                                       # cache可以存储工具执行的结果， 从而减少重新执行相同任务，默认是True\n",
    "            embedder={                                          # embedder可以配置为第三方的embedder，例如ollama\n",
    "                \"provider\": \"ollama\",\n",
    "                \"config\": {\n",
    "                    \"model\": \"mxbai-embed-large\"\n",
    "                }\n",
    "            },\n",
    "            full_output = True,                                  # 是否输出完整的输出，默认是False\n",
    "            step_callback = self.callback_function,              # 每个agent的每个步骤都调用的函数。这可以用来记录agent的动作或执行其他操作；它不会覆盖特定于agent的step_callback \n",
    "            task_callback = self.callback_function,              # 每个agent的每个任务都调用的函数。可用来执行任务后操作。\n",
    "            share_crew = False,                                  # 是否共享你的方案给crew官方，默认是False\n",
    "\n",
    "        )\n",
    "    \n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## kick off\n",
    "\n",
    "开球方式：使用适当的开球方法启动工作流程。 CREWAI提供了几种更好地控制开球过程的方法：\n",
    "\n",
    "    kickoff() ：根据定义的过程流启动执行过程。\n",
    "    kickoff_for_each() ：分别执行每个代理的任务。\n",
    "    kickoff_async() ：异步启动工作流程。\n",
    "    kickoff_for_each_async() ：以异步方式单独执行每个代理的任务。\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'crew' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "Cell \u001b[1;32mIn[1], line 2\u001b[0m\n\u001b[0;32m      1\u001b[0m \u001b[38;5;66;03m# Start the crew's task execution\u001b[39;00m\n\u001b[1;32m----> 2\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[43mcrew\u001b[49m\u001b[38;5;241m.\u001b[39mkickoff()\n\u001b[0;32m      3\u001b[0m \u001b[38;5;28mprint\u001b[39m(result)\n\u001b[0;32m      5\u001b[0m \u001b[38;5;66;03m# Example of using kickoff_for_each\u001b[39;00m\n",
      "\u001b[1;31mNameError\u001b[0m: name 'crew' is not defined"
     ]
    }
   ],
   "source": [
    "# Start the crew's task execution\n",
    "result = crew.kickoff()\n",
    "print(result)\n",
    "\n",
    "# Example of using kickoff_for_each\n",
    "inputs_array = [{'topic': 'AI in healthcare'}, {'topic': 'AI in finance'}]\n",
    "results = crew.kickoff_for_each(inputs=inputs_array)\n",
    "for result in results:\n",
    "    print(result)\n",
    "\n",
    "# Example of using kickoff_async\n",
    "inputs = {'topic': 'AI in healthcare'}\n",
    "async_result = crew.kickoff_async(inputs=inputs)\n",
    "print(async_result)\n",
    "\n",
    "# Example of using kickoff_for_each_async\n",
    "inputs_array = [{'topic': 'AI in healthcare'}, {'topic': 'AI in finance'}]\n",
    "async_results = crew.kickoff_for_each_async(inputs=inputs_array)\n",
    "for async_result in async_results:\n",
    "    print(async_result)\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
